package com.gjy.mongo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.MBeanServer;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * PoolBeanMonitor类实现了一个定时器，每隔5s输出连接池MBean的状态信息。
 * 监视驱动的连接数
 *
 * @author 宫静雨
 * @version 1.0
 * @since 2023-01-30 10:00:51
 */
public class PoolBeanMonitor implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(PoolBeanMonitor.class);
    private final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    private final ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);

    public void start() {
        logger.info("start monitoring for connection pool.");
        // 每五秒打印一次
        pool.scheduleAtFixedRate(this, 5, 5, TimeUnit.SECONDS);
    }

    public void stop() {
        this.pool.shutdown();
        logger.info("stop monitoring for connection pool.");
    }

    @Override
    public void run() {
        try {
            Set<ObjectInstance> instances = mBeanServer.queryMBeans(new ObjectName("org.mongodb.driver:type=ConnectionPool,*"), null);
            for (ObjectInstance instance : instances) {
                String className = instance.getClassName();
                if (!className.contains("mongo")) {
                    continue;
                }
                ObjectName objectName = instance.getObjectName();
                String[] attrs = {"CheckedOutCount", "Host", "Port", "MinSize", "MaxSize", "Size", "WaitQueueSize"};
                StringBuilder sb = new StringBuilder();
                for (String attr : attrs) {
                    sb.append(attr).append("-").append(mBeanServer.getAttribute(objectName, attr)).append("|");
                }
                logger.info("ConnPoolStatistic - {}: \n\t - {}", objectName, sb);
            }
        } catch (Exception e) {
            logger.error("error occurs", e);
        }
    }
}
